import { PrismaClientRustError } from '@prisma/client-runtime-utils'

export type LogLevel = 'info' | 'trace' | 'debug' | 'warn' | 'error' | 'query'
export interface RawRustLog {
  timestamp: string
  level: LogLevel
  target: string
  fields: LogFields
}

export interface RustLog {
  timestamp: Date
  level: LogLevel
  target: string
  fields: LogFields
}

export function getMessage(log: string | PrismaClientRustError): string {
  if (typeof log === 'string') {
    return log
  } else {
    return log.message
  }
}

export function isRustLog(e: any): e is RustLog {
  return e.timestamp && typeof e.level === 'string' && typeof e.target === 'string'
}

export function isRustErrorLog(e: any): e is RustLog {
  return isRustLog(e) && (e.level === 'error' || e.fields?.message?.includes('fatal error'))
}

export type LogFields = { [key: string]: any }

export interface QueryLogFields {
  query: string
  item_type: string
  params: string
  duration_ms: number
}

export function convertLog(rustLog: RawRustLog): RustLog {
  const isQuery = isQueryLog(rustLog.fields)
  const level: LogLevel = isQuery ? 'query' : (rustLog.level.toLowerCase() as LogLevel)
  return {
    ...rustLog,
    level,
    timestamp: new Date(rustLog.timestamp),
  }
}

function isQueryLog(fields: any): fields is QueryLogFields {
  return Boolean(fields.query)
}
